#ifndef DRV_H
#define DRV_H
/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/
#define TAHITI   0
#define PITCAIRN 1
#define VERDE    2
#define OLAND    3
/*
 * DCE-less HAINAN would be 4, but it's worth a separated module with hardcore
 * simple code paths
 */

#define SI_ERR 900
#define USEC_TIMEOUT 100000 /* 100000 us = 100 ms */

struct cfg {
	u32 addr_best;
	u8 dce_crtcs_n;
	struct gpu_cfg gpu;
};

struct clks_regs {
	u32 cg_eng_pll_func_ctl_0;
	u32 cg_eng_pll_func_ctl_1;
	u32 cg_eng_pll_func_ctl_2;
	u32 cg_eng_pll_func_ctl_3;
	u32 cg_eng_pll_ss_0;
	u32 cg_eng_pll_ss_1;
	u32 dll_ctl;
	u32 mem_clk_pm_ctl;
	u32 mem_pll_ad_func_ctl;
	u32 mem_pll_dq_func_ctl;
	u32 mem_pll_func_ctl_0;
	u32 mem_pll_func_ctl_1;
	u32 mem_pll_func_ctl_2;
	u32 mem_pll_ss_0;
	u32 mem_pll_ss_1;
};

struct pp {
	/*--------------------------------------------------------------------*/
	/* default/boot/initial values */
	u32 default_eng_clk;		/* 10 kHz units */
	u32 default_mem_clk;		/* 10 kHz units */
	u16 default_vddc;		/* mV units */
	u16 default_vddci;		/* mV units */
	u16 default_mvddc;		/* mV units */
	u8 default_pcie_gen;		/* used in dynamic power management */
	u8 default_pcie_lanes_n;	/* used in dynamic power management */
	struct clks_regs clks_regs;	/* used in dynamic power management */
	/*--------------------------------------------------------------------*/
};

struct dev_drv_data {
	u8 family;
	struct cfg cfg;

	struct atombios *atb;
	const struct firmware *mc_fw;
	u32 mc_fw_dws;
	const struct firmware *rlc_fw;
	const struct firmware *pfp_fw;
	const struct firmware *ce_fw;
	const struct firmware *me_fw;
	const struct firmware *smc_fw;
	u32 smc_fw_dws;

	struct pp pp;

	struct dce6 *dce;

	u8 asic_inited;

	u32 addr_cfg;
	u32 mem_row_sz_kb;

	void __iomem *regs;
	u32 regs_sz;
	struct vram vram;
	struct ba ba;
	struct cp_ring gpu_3d;
	struct cp_ring gpu_c0;
	struct cp_ring gpu_c1;
	struct ih ih;
	struct rlc rlc;

	atomic_t dmas_selector;
	struct dma dmas[DMAS_N];

	/* userland */
	unsigned minor;
	struct cdev char_cdev;
	struct device char_dev;
	struct pci_dev *dev; 
};

u32 rr32(struct pci_dev *dev, u32 aligned_of);
void wr32(struct pci_dev *dev, u32 val, u32 aligned_of);
u32 vram_r32(struct pci_dev *dev, u64 aligned_of);
void vram_w32(struct pci_dev *dev, u32 val, u64 aligned_of);
#endif /* _DRV_H */
